﻿/*
	练习一道题目
输入一个长度为n的整数序列。
接下来再输入m个询问，每个询问输入一对l, r。
对于每个询问，输出原序列中从第l个数到第r个数的和。
输入格式
第一行包含两个整数n和m。
第二行包含n个整数，表示整数数列。
接下来m行，每行包含两个整数l和r，表示一个询问的区间范围。
输出格式
共m行，每行输出一个询问的结果。
数据范围
1≤l≤r≤n,
1≤n,m≤100000,
−1000≤数列中元素的值≤1000
————————————————
*/

//#include <iostream>
//
//using namespace std;
//
//const int N = 100010;
//
//int n, m;
//int a[N], s[N];
//
//int main()
//{
//    cin >> n >> m;
//    for (int i = 1; i <= n; i++) 
//        cin >> a[i];
//
//    for (int i = 1; i <= n; i++) 
//        s[i] = s[i - 1] + a[i]; // 前缀和的初始化
//
//    while (m--)
//    {
//        int l, r;
//        cin >> l >> r;
//        printf("%d\n", s[r] - s[l - 1]); // 区间和的计算
//    }
//
//    return 0;
//}

//#include <iostream>
//#include <vector>
//#include <algorithm>
//
//using namespace std;
//
//int minSubArrayLen(int target, vector<int>& nums) {
//    int len = 0x3f3f3f3f, n = nums.size();//让len为最大值防止没有符合要求时返回0，如果刚开始设置为零那么就一直是0因为是min
//    int sum = 0;//求和
//    for (int left = 0, right = 0; right < n; right++) {
//        sum += nums[right];//从right进窗口，方便
//        while (sum >= target) {//找到符合要求
//            len = min(len, right - left + 1);//判断长度
//            sum -= nums[left];//出窗口，不用向右走了因为再向右即使也有符合要求的但是长度不是最小的
//            left++;//改变左窗口使成为新的窗口
//        }
//    }
//    return len == 0x3f3f3f3f ? 0 : len;//如果没有符合要求的返回0
//}
//
//int main()
//{
//    vector<int> v;
//    v.push_back(2);
//    v.push_back(3);
//    v.push_back(1);
//    v.push_back(2);
//    v.push_back(4);
//    v.push_back(3);
//
//    minSubArrayLen(7, v);
//    return 0;
//}

#include <iostream>
#include <vector>
#include <algorithm>
#include <map>

using namespace std;
using ll = long long;
const int N = 1e5 + 9;
int n, k;
int a[N];

struct edge {
    int y, w;
};

vector<edge> g[N];
typedef pair<int, int> pii;
map<pii, int> st; // x到y的距离

// 参数：起点，当前点，父节点，终点
bool dfs(int start, int md, int father, int end, ll sum) {
    // 返回条件
    if (md == end) {
        st[{end, start}] = st[{start, end}] = sum;
        return true;
    }

    for (vector<edge> ::iterator it = g[md].begin(); it != g[md].end(); it++) {
        int son = it->y;
        // 如果遍历到父节点跳过
        if (son == father)
            continue;

        int w = it->w;
        // 如果能找到目标点则返回
        if (dfs(start, son, md, end, sum + w))
            return true;
    }
    return false;
}

int main()
{
    cin >> n >> k;
    for (int i = 0; i < n - 1; i++) {
        int x, y, w; cin >> x >> y >> w;
        g[x].push_back({ y, w });
        g[y].push_back({ x, w });
    }
    for (int i = 0; i < k; i++) 
        cin >> a[i];

    ll ans = 0;
    // 求出路线总路径sum
    for (int i = 0; i < k; i++) {
        dfs(a[i], a[i], -1, a[i + 1], 0);
        ans += st[{a[i], a[i + 1]}];
    }
    // 遍历跳过的点
    for (int i = 0; i < k; i++) {
        ll tmp = ans;
        //  如果跳过的景点是第一个或最后一个，则时间花费直接减去2 -> 6或者5 -> 1
        if (i == 0)
            tmp -= st[{a[i], a[i + 1]}];
        else if (i == k - 1)
            tmp -= st[{a[i - 1], a[i]}];
        else {
            // 如果是中间点先减去前一个和后一个景点到它的距离，再把前一个景点到后一个景点距离通过dfs算出来
            tmp -= st[{a[i - 1], a[i]}];
            tmp -= st[{a[i], a[i + 1]}];
            dfs(a[i - 1], a[i - 1], -1, a[i + 1], 0);
            tmp += st[{a[i - 1], a[i + 1]}];

        }
        cout << tmp << ' ';

    }
    return 0;
}